import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

///防止多次点击的控件
class FxClick extends StatelessWidget {
  ///如果child包含Container并且设置颜色属性，则点击的水波纹效果会消失
  final Widget child;
  ///按钮颜色
  final Color? color;
  final double? width;
  final double? height;
  final Decoration? decoration;
  final BorderRadius? borderRadius;

  ///处理点击事件的  防抖、方法请求结束后才能继续点击
  final DebounceClickDelegate clickDelegate;

  FxClick({
    Key? key,
    required this.child,
    Function()? onTap,
    Function()? onLongPress,
    this.color,
    this.borderRadius,
    this.decoration,
    this.width,
    this.height,
    bool debounce = true,
    bool asyncTap = true,
  })  : clickDelegate = DebounceClickDelegate(
            debounce: debounce,
            onTap: onTap,
            asyncTap: asyncTap,
            onLongTap: onLongPress),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return _hasWaveView();
  }

  ///使用InkWell自带的波纹点击效果
  Widget _hasWaveView() {
    return Material(
      borderRadius: borderRadius,
      color: Colors.transparent,
      child: Ink(
        color: color,
        width: width,
        height: height,
        decoration: decoration,
        child: InkWell(
          borderRadius: borderRadius,
          onTap: clickDelegate.tap,
          onLongPress: clickDelegate.longTap,
          child: child,
        ),
      ),
    );
  }
}

///防抖
class DebounceClickDelegate {
  final Function()? onTap;
  final Function()? onLongTap;
  final bool debounce;
  final bool asyncTap;
  int time = -1;
  bool clicking = false;

  /// 目前来说，1s够用了 500ms好像有点小问题
  static const int DELAY = 1000;

  DebounceClickDelegate(
      {required this.debounce,
      this.asyncTap = true,
      this.onTap,
      this.onLongTap});

  void tap() {
    if (allowExecute()) _asyncTap(onTap);
  }

  void longTap() {
    if (allowExecute()) _asyncTap(onLongTap);
  }

  bool allowExecute() {
    if (debounce) {
      final current = DateTime.now().millisecondsSinceEpoch;
      if (current - time >= DELAY) {
        // print("-----------------------allow debounce dis time ${current - time}");
        time = current;
        return true;
      }
      return false;
    }
    return true;
  }

  _asyncTap(Function()? tap) async {
    //不等待执行完
    if(!asyncTap){
      tap?.call();
      return;
    }
    //等待执行完，才可以继续点击
    if (clicking) return false;
    clicking = true;
    //增加onError，防止异常导致一直无法点击
    await _onTapCall(tap).onError((error, stackTrace) {
      if (kDebugMode) print("$error \n $stackTrace");
    }).whenComplete((){
      clicking = false;
    });
  }

  Future _onTapCall(Function()? tap) async {
    return await tap?.call();
  }
}

class InkClick extends InkWell {
  InkClick(
      {required Widget child,
      super.onTap,
      super.onLongPress,
      Color color = Colors.white,
      EdgeInsetsGeometry? padding,
      double? width,
      double? height,
      BorderRadius? radius})
      : super(
            borderRadius: radius ?? BorderRadius.circular(5),
            child: Ink(
                padding: padding,
                width: width,
                height: height,
                decoration: BoxDecoration(
                    color: color,
                    borderRadius: radius ?? BorderRadius.circular(5)),
                child: child));
}